#include "debug.h"

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

bool debugMsgDisplay  = true;
FILE * debugMsgStream = NULL;


void
enableDebugMsg ()
{
  extern bool debugMsgDisplay;
  debugMsgDisplay = true;
  return ;
}

void
disableDebugMsg ()
{
  extern bool debugMsgDisplay;
  debugMsgDisplay = false;
  return ;
}

void
debugMsgOutput (FILE * fs)
{
  extern FILE * debugMsgStream ;
  debugMsgStream = fs;
  return ;
}



void
DEBUGMSG (int debug, const char * file, int line, 
	  const char * func, const char *fmt, ...)
{
#ifdef ENABLE_DEBUG
  extern bool debugMsgDisplay;
  extern FILE * debugMsgStream ;

  struct tm timeData;
  struct timeval tv;
  struct timezone tz;

  FILE * output;
  va_list args;

  if (debug != true || debugMsgDisplay != true)
    return ;

  output = (debugMsgStream == NULL) ? stdout : debugMsgStream;

  va_start (args, fmt);

  gettimeofday (&tv, &tz);
  localtime_r (&tv.tv_sec, &timeData);  

  fprintf (output, "(DEBUG %02d:%02d:%02d.%03d %s:%d %s) ",
	   timeData.tm_hour, timeData.tm_min, timeData.tm_sec,
	   (int) (tv.tv_usec / 1000), file, line, func);

  vfprintf (output, fmt, args);
  va_end (args);

  if (fmt[strlen (fmt) - 1] != '\n')
    printf ("\n");

  fflush (output);
#endif
  return;
}

#define BUFSIZE 4096

void 
RAWMSG (int debug, int len, u_int8_t * data, 
	const char * file, int line, const char * func, char *fmt, ...)
{
#ifdef ENABLE_DEBUG
  extern FILE * debugMsgStream ;

  struct tm timeData;
  struct timeval tv;
  struct timezone tz;

  FILE * output;
  va_list args;
  char buf[BUFSIZE];
  char * msg = "";
  int i;

  if (debug != true || debugMsgDisplay != true || len == 0)
    return ;

  output = (debugMsgStream == NULL) ? stdout : debugMsgStream;

  if (sizeof (buf) <= len)
    msg = " **OVER SIZE**";

  gettimeofday (&tv, &tz);
  localtime_r (&tv.tv_sec, &timeData);  

  fprintf (output, "(RAW %02d:%02d:%02d.%03d %s:%d %s%s) \"",
	   timeData.tm_hour, timeData.tm_min, timeData.tm_sec,
	   (int) (tv.tv_usec / 1000), file, line, func, msg);

  for (i = 0; i < len && i < sizeof (buf) - 1; i++)
    buf [i] = (isprint (data[i]) ? data [i] : '.');
  buf [i] = '\0';

  va_start (args, fmt);
  vfprintf (output, fmt, args);
  va_end (args);

  fprintf (output, "\" %s\n", buf);

  fflush (output);
#endif
  return;
}

void 
HEXMSG (int debug, int len, u_int8_t * data, 
	const char * file, int line, const char * func, char *fmt, ...)
{
#ifdef ENABLE_DEBUG
  extern FILE * debugMsgStream ;

  struct tm timeData;
  struct timeval tv;
  struct timezone tz;

  FILE * output;
  va_list args;
  int i, c;

  if (debug != true || debugMsgDisplay != true || len == 0)
    return ;

  output = (debugMsgStream == NULL) ? stdout : debugMsgStream;


  gettimeofday (&tv, &tz);
  localtime_r (&tv.tv_sec, &timeData);  

  fprintf (output, "(HEX %02d:%02d:%02d.%03d %s:%d %s) ",
	   timeData.tm_hour, timeData.tm_min, timeData.tm_sec,
	   (int) (tv.tv_usec / 1000), file, line, func);

  va_start (args, fmt);
  vfprintf (output, fmt, args);
  va_end (args);

  fprintf (output, " [%d byte]\n", len);

  
  for (c = 0; c < len + 16; c += 16)
    {
      fprintf (output, "\t");
      for (i = c ; i < c + 16 ; i++)
	{
	  if (i == c + 8)
	    fprintf (output, " ");

	  if (i < len)
	    fprintf (output, "%02X ", data[i]);
	  else
	    fprintf (output, "   ");
	}

      fprintf (output, "  ");
      for (i = c ; i < c + 16 ; i++)
	{
	  if (i < len)
	    fprintf (output, "%c", (isprint (data[i]) ? data [i] : '.'));
	  else
	    fprintf (output, " ");
	}
      
      fprintf (output, "\n");
    }

  fflush (output);
#endif
  return;
}

void
debugPoint ()
{
  return ;
}
